package com.dawnling.androidutils.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.PathEffect;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.blankj.utilcode.util.LogUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class MyPaintView1 extends View {

    //圆点数组
    private List<Point> roundPoints = new ArrayList<>();
    private float dashSize = 10;//虚线大小

    //接受context以及属性集合(宽度，高度等)
    public MyPaintView1(Context context, AttributeSet attrs) {
        super(context, attrs);
        super.setOnTouchListener(new OnTouchListenerImp());
    }

    /**
     * 动作常量：
     * MotionEvent.ACTION_DOWN：当屏幕检测到第一个触点按下之后就会触发到这个事件。
     * MotionEvent.ACTION_MOVE：当触点在屏幕上移动时触发，触点在屏幕上停留也是会触发的，主要是由于它的灵敏度很高，而我们的手指又不可能完全静止（即使我们感觉不到移动，但其实我们的手指也在不停地抖动）。
     * MotionEvent.ACTION_POINTER_DOWN：当屏幕上已经有触点处于按下的状态的时候，再有新的触点被按下时触发。
     * MotionEvent.ACTION_POINTER_UP：当屏幕上有多个点被按住，松开其中一个点时触发（即非最后一个点被放开时）触发。
     * MotionEvent.ACTION_UP：当触点松开时被触发。
     * MotionEvent.ACTION_OUTSIDE: 表示用户触碰超出了正常的UI边界.
     * MotionEvent.ACTION_SCROLL：android3.1引入，非触摸滚动，主要是由鼠标、滚轮、轨迹球触发。
     * MotionEvent.ACTION_CANCEL：不是由用户直接触发，由系统在需要的时候触发，例如当父view通过使函数onInterceptTouchEvent()返回true,从子view拿回处理事件的控制权时，就会给子view发一个ACTION_CANCEL事件，子view就再也不会收到后续事件了。
     */
    private class OnTouchListenerImp implements OnTouchListener {
        public boolean onTouch(View v, MotionEvent event) {
            Point p = new Point((int) event.getX(), (int) event.getY());
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                //用户按下，表示重新开始保存点
                LogUtils.e("onTouch ACTION_DOWN" + "{" + p.x + "," + p.y + "}");
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                //用户松开
                LogUtils.e("onTouch ACTION_UP" + "{" + p.x + "," + p.y + "}");
                MyPaintView1.this.roundPoints.add(p);
                MyPaintView1.this.postInvalidate();//重绘图像
            } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                LogUtils.e("onTouch ACTION_MOVE" + "{" + p.x + "," + p.y + "}");
            }
            return true;
        }
    }

    @SuppressLint("MissingSuperCall")
    @Override
    public void draw(Canvas canvas) {
        Paint p = new Paint();//依靠此类开始画线
        p.setColor(Color.BLUE);
        p.setStrokeWidth(3);
        p.setAntiAlias(true);
        PathEffect pathEffect = new DashPathEffect(new float[]{dashSize, dashSize, dashSize, dashSize}, 1);
        p.setPathEffect(pathEffect);

        List<Point> roundPoints = MyPaintView1.this.roundPoints;
        for (int i = 0; i < roundPoints.size(); i++) {
            //画圆点 定义一个矩形区域
            canvas.drawCircle(roundPoints.get(i).x, roundPoints.get(i).y, 10, p);
        }
        if (roundPoints.size() > 1) {
            //如果有坐标点，开始绘图
            Iterator<Point> iter = roundPoints.iterator();
            Point firstOriginal = null;//第一个点 原点保持不变
            Point first = null;
            Point last = null;
            while (iter.hasNext()) {
                if (firstOriginal == null) firstOriginal = iter.next();
                if (first == null) {
                    first = firstOriginal;//绘制线的起点
                } else {
                    if (last != null) first = last;
                    last = iter.next();////绘制线的结束点
                    canvas.drawLine(first.x, first.y, last.x, last.y, p);
                }
                //绘制闭合点
                if (roundPoints.size() > 2 && !iter.hasNext()) {
                    canvas.drawLine(last.x, last.y, firstOriginal.x, firstOriginal.y, p);
                }
            }
        }
    }

    /**
     * 对画布进行清屏
     */
    public void clearDraw() {
        roundPoints.clear();
        invalidate();
    }
}
